﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Task
{
    public struct myclr
    {
        public int r;
        public int g;
        public int b;
    };


    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();

        }

        Bitmap loaded_image;//de el bmp image ely nada bet3mlaha load fe 2D buffer (struct)
       
        myclr[,] clr;//da el 2D buffer ely 3amlna feeh load lel bmp image
        
        myclr[,] new_clr;//da el result beta3 el resize
        
        myclr[,] buffered;//da el sora ely fe picutrebox1 ba3d el load wel rotation 
        
        myclr[,] buffered_for_resize;//de 3alashan lw 3ayza a3mel resize lel sora w hea already rotated
        
        bool flipped = false;//dost 3la zorar flipped wla l2 

        int rotation_level = 0;// da 3alashan a3raf hea lafet kam mara till now
        
        int buffered_width, buffered_height;//da el width wel height beta3 buffered ba3d kol mara yet3ml 3alih ay operation
   
        /// <summary>
        /// function bet3ml load 3ady le image 3adeya (bmp,jpg,...) fe 2D array mn noo3 struct myclr
        /// </summary>
        private void Load_Image()
        {
            string exePath ;//= Application.StartupPath + "\\Jaguar.bmp";// 3alashan mayedrabsh lma ne3'ayar el path beta3 el images ely bensta5demha w kol el files betet7at fe bin\\debug

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                exePath = openFileDialog1.FileName;
                if ((exePath.Substring(openFileDialog1.FileName.Length - 3).ToLower() != "bmp") && (exePath.Substring(openFileDialog1.FileName.Length - 3).ToLower() != "jpg"))
                {
                    MessageBox.Show("This is not a bmp nor a jpg image file");
                    return;
                }
            }
            else
                return;

            loaded_image = new Bitmap(exePath);
            pictureBox1.Image = loaded_image;
            clr = new myclr[loaded_image.Width, loaded_image.Height];
            Loaded_image_height.Text = "loaded height =" + Convert.ToString(loaded_image.Height);
            loaded_image_width.Text = "loaded width =" + Convert.ToString(loaded_image.Width);


            int i, j;
            for (i = 0; i < loaded_image.Width; i++)
            {
                for (j = 0; j < loaded_image.Height; j++)
                {
                    clr[i, j].r = loaded_image.GetPixel(i, j).R;
                    clr[i, j].g = loaded_image.GetPixel(i, j).G;
                    clr[i, j].b = loaded_image.GetPixel(i, j).B;

                }
            }
            buffered = clr;
            buffered_for_resize = clr;
            rotation_level = 0;
            buffered_width = loaded_image.Width;
            buffered_height = loaded_image.Height;
            flipped = false;
        }


        /// <summary>
        /// de function bet3ml display le image e7na le3bna feeha w hea 7aleyan mawgooda fe buffer e7na 3amleno (mn noo3 struct) 
        /// fa beta5od el width wel height beta3et el array ely shayel el sora (el dimensions beta3to y3ni) wel array ely shayel 
        /// el sora ely 3ayza a3melaha display
      /// </summary>
      /// <param name="width"></param>
      /// <param name="height"></param>
      /// <param name="image"></param>
      /// <param name="resize"></param>// da 3alashan lw bey3ml resize ye3red el nateega fe picturebox2 msh 1
        private void Display_image(int width, int height, myclr[,] image,bool resize)
        {
            Color c;
            Bitmap resulted_image = new Bitmap(width,height);//new bitmap object agamma3 feeh el sora ely 3ayza a3redha pixel by pixel 3alashan a3raf a7otaha fe picturebox

            for (int i = 0; i < resulted_image.Width; i++)
            {
                for (int j = 0; j < resulted_image.Height; j++)
                {
                    c = Color.FromArgb(image[i, j].r, image[i, j].g, image[i, j].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)
                    resulted_image.SetPixel(i, j, c);
                }
            }
            if(resize)
                pictureBox2.Image = resulted_image;
            else
            pictureBox1.Image = resulted_image;

        }

    
        /// <summary>
        /// de bet3kes el sora ely fe picturebox1 ka2enaha meraya
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="image"></param>
        private void Flip_image(int width, int height, myclr[,] image)
        {
            if (flipped)
                return;
            Color c;
            Bitmap resulted_image = new Bitmap(width, height);//new bitmap object agamma3 feeh el sora ely 3ayza a3redha pixel by pixel 3alashan a3raf a7otaha fe picturebox
           // buffered=new myclr[height,width];
            int x = 0;
            int y = 0;
          if(rotation_level==0)
          {
            
            for (int i = resulted_image.Width - 1; i >=0 ; i--)
            {

                for (int j = 0; j <  resulted_image.Height-1 ; j++)
                {
                    c = Color.FromArgb(image[i, j].r, image[i, j].g, image[i, j].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)
                    resulted_image.SetPixel(x, j, c);

                }
                x++;
            }
        }
           else if (rotation_level == 1)
            {

                for (int i = resulted_image.Width - 1; i >= 0; i--)
                {
                    y = 0;
                    for (int j = resulted_image.Height - 1; j >= 0; j--)
                    {
                        c = Color.FromArgb(image[i, j].r, image[i, j].g, image[i, j].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)

                        resulted_image.SetPixel(x, y, c);
                        y++;
                    }
                    x++;
                }
            }
            else if (rotation_level == 2)
            {

                for (int i = resulted_image.Width - 1; i >= 0; i--)
                {
                    y = 0;
                    for (int j = resulted_image.Height - 1; j >=0 ; j--)
                    {
                        c = Color.FromArgb(image[i, j].r, image[i, j].g, image[i, j].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)

                        resulted_image.SetPixel(x, y, c);
                        y++;
                    }
                    x++;
                }
            }
            else if (rotation_level == 3)
            {

                for (int i = resulted_image.Width - 1; i >= 0; i--)
                {
                    y = 0;
                    for (int j = 0; j < resulted_image.Height - 1; j++)
                    {
                        c = Color.FromArgb(image[i, j].r, image[i, j].g, image[i, j].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)
                        resulted_image.SetPixel(i, j, c);
                        y++;
                    }
                    x++;
                }
            }



            pictureBox2.Image = resulted_image;

        }

       
        /// <summary>
        /// bet3ml rotation lel image ely fe picturebox1 by 90 degree clockwise
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="image"></param>
        private void rotate_image(int width, int height, myclr[,] image)
        {
            Color c;
            Bitmap resulted_image = new Bitmap(height,width);//new bitmap object agamma3 feeh el sora ely 3ayza a3redha pixel by pixel 3alashan a3raf a7otaha fe picturebox
            buffered = new myclr[height, width];
            buffered_for_resize = new myclr[height, width]; 
            buffered_width = height;
            buffered_height = width;

            Loaded_image_height.Text = "loaded height =" + Convert.ToString(width);
            loaded_image_width.Text = "loaded width =" + Convert.ToString(height);
            int x = 0;
            int y ;
            if (rotation_level == 0)
            {

                for (int i = resulted_image.Width - 1; i >= 0; i--)
                {
                    y = 0;
                    for (int j = resulted_image.Height - 1; j >= 0; j--)
                    {
                        c = Color.FromArgb(image[j, i].r, image[j, i].g, image[j, i].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)
                        buffered[x, y].r = image[j, i].r;
                        buffered[x, y].b = image[j, i].b;
                        buffered[x, y].g = image[j, i].g;

                        buffered_for_resize[x, j].r = image[j, i].r;
                        buffered_for_resize[x, j].b = image[j, i].b;
                        buffered_for_resize[x, j].g = image[j, i].g;
                        resulted_image.SetPixel(x, j, c);
                        y++;
                    }
                    x++;
                }
            }
            else if (rotation_level == 1)
            {

                for (int i = 0; i < resulted_image.Width; i++)
                {
                    y = 0;
                    for (int j = resulted_image.Height - 1; j >= 0; j--)
                    {
                        c = Color.FromArgb(image[j, i].r, image[j, i].g, image[j, i].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)
                        buffered[x, y].r = image[j, i].r;
                        buffered[x, y].b = image[j, i].b;
                        buffered[x, y].g = image[j, i].g;
                        buffered_for_resize[x, j].r = image[j, i].r;
                        buffered_for_resize[x, j].b = image[j, i].b;
                        buffered_for_resize[x, j].g = image[j, i].g;
                        resulted_image.SetPixel(x, j, c);
                        y++;
                    }
                    x++;
                }
            }
            else if (rotation_level == 2)
            {

                for (int i = resulted_image.Width - 1; i >= 0; i--)
                {
                    y = 0;
                    for (int j = 0; j < resulted_image.Height - 1; j++)
                    {
                        c = Color.FromArgb(image[j, i].r, image[j, i].g, image[j, i].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)
                        buffered[x, y].r = image[j, i].r;
                        buffered[x, y].b = image[j, i].b;
                        buffered[x, y].g = image[j, i].g;
                        buffered_for_resize[i, j].r = image[j, i].r;
                        buffered_for_resize[i, j].b = image[j, i].b;
                        buffered_for_resize[i, j].g = image[j, i].g;
                        resulted_image.SetPixel(i, j, c);
                        y++;
                    }
                    x++;
                }
            }
            else if (rotation_level == 3)
            {

                for (int i = resulted_image.Width - 1; i >= 0; i--)
                {
                    y = 0;
                    for (int j = resulted_image.Height - 1; j >= 0; j--)
                    {
                        c = Color.FromArgb(image[j, i].r, image[j, i].g, image[j, i].b);// da bagamma3 feeh el loon tany m3 ba3d(the saved values of R,G,B of each pixel)
                        buffered[x, y].r = image[j, i].r;
                        buffered[x, y].b = image[j, i].b;
                        buffered[x, y].g = image[j, i].g;
                        buffered_for_resize[x, y].r = image[j, i].r;
                        buffered_for_resize[x, y].b = image[j, i].b;
                        buffered_for_resize[x, y].g = image[j, i].g;
                        resulted_image.SetPixel(x, y, c);
                        y++;
                    }
                    x++;
                }
            }
            pictureBox1.Image = resulted_image;

        }


        /// <summary>
        /// ba3mel save le image be formate p3 images w beta5od el dimensions beta3et el buffer ely hea metsayeva feeh
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="p3_image"></param>
        private void save_p3_image(int width, int height, myclr[,] p3_image)
        {
            string path;
            SaveFileDialog save = new SaveFileDialog();
            if (save.ShowDialog() == DialogResult.OK)
            {
                path = save.FileName+".ppm";
            }
            else
                return;
            // = Application.StartupPath + "\\Saved_P3.ppm";
            StreamWriter SW = new StreamWriter(path, false);
            SW.WriteLine("P3");
            SW.WriteLine("#Created by ANA :D");
            SW.WriteLine(height + " " + width);
            SW.WriteLine("255");
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    SW.Write(p3_image[i, j].r + " " + p3_image[i, j].g + " " + p3_image[i, j].b + " ");
                }
            }
            SW.Close();
        }


        /// <summary>
        /// opens a P3 image chose from a file dialoge
        /// </summary>
        private void open_p3_image()
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                if (openFileDialog1.FileName.Substring(openFileDialog1.FileName.Length - 3).ToLower() != "ppm")
                {
                    MessageBox.Show("This is not a P3 image file");
                    return;
                }
            }

            StreamReader SR = new StreamReader(openFileDialog1.FileName);
            string[] P3_Dim_Arr = new string[1];

            string[] Arr_Colors = new string[2072641];
            if (SR.ReadLine() != "P3")
            {
                MessageBox.Show("Wrong P3 File Format");
                return;
            }

            string P3_Dim = SR.ReadLine();
            if (P3_Dim[0] == '#')
            {
                P3_Dim = SR.ReadLine();
            }
            P3_Dim_Arr = P3_Dim.Split(' ');
            int P3_Width;
            int P3_Height;

            P3_Width = int.Parse(P3_Dim_Arr[1]);
            P3_Height = int.Parse(P3_Dim_Arr[0]);

            SR.ReadLine();//da el 255

            string Rest_Colors = SR.ReadToEnd();
            Arr_Colors = Rest_Colors.Split(' ');

            Bitmap Bmp_Obj = new Bitmap(P3_Width, P3_Height);
            Color CLR_Obj;
            int Curr_Clr = 0;

            myclr[,] buffer = new myclr[P3_Width, P3_Height];
            Loaded_image_height.Text = "loaded height =" + P3_Height;
            loaded_image_width.Text = "loaded width =" + P3_Width;


            for (int i = 0; i < P3_Width; i++)
            {
                for (int j = 0; j < P3_Height; j++)
                {
                    buffer[i, j].r = int.Parse(Arr_Colors[Curr_Clr]);
                    buffer[i, j].g = int.Parse(Arr_Colors[Curr_Clr + 1]);
                    buffer[i, j].b = int.Parse(Arr_Colors[Curr_Clr + 2]);

                    CLR_Obj = Color.FromArgb(buffer[i, j].r, buffer[i, j].g, buffer[i, j].b);
                    Bmp_Obj.SetPixel(i, j, CLR_Obj);
                    Curr_Clr = Curr_Clr + 3;

                }
            }
            SR.Close();

            buffered_for_resize = buffer;
            buffered = buffer;

            Display_image(P3_Width, P3_Height, buffer, false);
            rotation_level = 0;
            buffered_width = P3_Width;
            buffered_height = P3_Height;
            flipped = false;
        }


        private void button1_Click(object sender, EventArgs e)
        {
            
            Load_Image();
        
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (buffered_for_resize == null)
            {
                MessageBox.Show("No images are loaded");
                return;
            }
            save_p3_image(buffered_width, buffered_height, buffered_for_resize);

        }

        private void button3_Click(object sender, EventArgs e)
        {
            
            open_p3_image();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            
            Flip_image(pictureBox1.Image.Width, pictureBox1.Image.Height,buffered);
    
        }

        private void button5_Click(object sender, EventArgs e)
        {

            
            rotate_image(pictureBox1.Image.Width, pictureBox1.Image.Height, buffered);
            if (rotation_level == 3)
                rotation_level = 0;
            else
            rotation_level++;
            
        }

        private void Button_resize_bilinear_Click(object sender, EventArgs e)
        {
            if (buffered_for_resize == null)
            {
                MessageBox.Show("Load image first");
                return;
            }

            int new_width, new_height;
            try
            {
                new_width = int.Parse(textBox_new_width.Text);
                new_height = int.Parse(textBox_new_height.Text);
            }
            catch
            {
                MessageBox.Show("Check the values of the textboxes");
                return;

            }

            Resizing resize = new Resizing();
            new_clr = resize.bilinear_resize(buffered_width,buffered_height,new_width ,new_height , buffered_for_resize);
            Display_image(new_width, new_height, new_clr, true);
           

        }

        private void button_Translate_Click(object sender, EventArgs e)
        {

            Transform Obj_Transform = new Transform();
            pictureBox2.Image = Obj_Transform.Translate(loaded_image.Width, loaded_image.Height, int.Parse(textBox_xpos.Text), int.Parse(textBox_ypos.Text), clr);
          
        }

       
    }
}
